package com.jrx.anytxn.common.uitl;

import com.google.common.base.Strings;
import org.joda.time.DateTime;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
 * 常用的时间工具
 *
 * @author dengguoqing
 * @date 2018-08-27
 */
public class DateUtils {

    /**
     * 时间格式(yyyy-MM-dd)
     */
    public static final String DATE_PATTERN = "yyyy-MM-dd";

    public static final String DATE_PATTERN_ANOTHER = "yyyyMMdd";

    public static final String DATE_PATTERN_ZH = "yyyy年MM月dd日";

    public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public static final String TIME_PATTERN = "HH:mm:ss";

    public static final String TIME_PATTERN_ANOTHER = "HHmmss";

    public static final String PART_DATETIME_PATTERN = "yyyyMMddHHmmss";

    public static final String ALL_DATETIME_PATTERN = "yyyyMMddHHmmssSSS";

    public static final String YEAR_MONTH_PATTERN = "yyyyMM";

    public static final String DATE_PATTERN_LINE = "yyyy/MM/dd";

    /**
     * 两个日期进行比较,第一个日期或第二个日期为空时返回1
     * 若第一个日期大于第二个日期返回1，第一个日期等于第二个日期返回-1，第一个日期等于第二个日期返回0
     *
     * @param date1 localDate
     * @param date2 localDate
     * @return int
     */
    public static int compareTwoLocalDate(LocalDate date1, LocalDate date2) {
        if (null == date2 || null == date1) {
            return 1;
        }
        return date1.compareTo(date2);
    }


    /**
     * 将格式为"yyyy-MM-dd HH:mm:ss"的字符串转化为LocalDateTime
     *
     * @param localDate 时间字符串
     * @return LocalDateTime
     */
    public static LocalDateTime parse2LocalDateTime(String localDate) {
        DateTimeFormatter dateTimeFormatter =
                DateTimeFormatter.ofPattern(DATETIME_PATTERN);
        return LocalDateTime.parse(localDate, dateTimeFormatter);
    }

    public static LocalDateTime parse2LocalDateTime(String localDate, String pattern) {
        if (null == pattern || "".equals(pattern.trim())) {
            return parse2LocalDateTime(localDate);
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(localDate, dateTimeFormatter);
    }

    public static LocalDate addDayFromDate2LocalDate(Date date, int day) {
        LocalDate result = dateConvertToLocalDate(date);
        return result.plusDays(day);
    }

    /**
     * 将日期转换为字符串
     *
     * @param date 输入日期 yyyy-MM-dd
     * @return String
     */
    public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    /**
     * 将日期转换为字符串 yyyy年MM月dd日
     *
     * @param date 输入日期
     * @return String
     */
    public static String formatZH(Date date) {
        return format(date, DATE_PATTERN_ZH);
    }

    public static String format(Date date, String pattern) {
        if (date != null) {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 生成指定年，月，日的日期
     *
     * @param year  年份
     * @param month 月份
     * @param date  日期
     * @return Date
     */
    public static Date date(int year, int month, int date) {
        LocalDate localDate = LocalDate.of(year, month, date);
        return localDateConvertToDate(localDate);
    }


    /**
     * java8中的LocalDate转为Date
     *
     * @param localDate java8日期
     * @return Date
     */
    public static Date localDateConvertToDate(LocalDate localDate) {
        if (localDate == null) {
            return null;
        }
        return new Date(localDate.getYear() - 1900, localDate.getMonthValue() - 1,
                localDate.getDayOfMonth());
    }

    /**
     * 将Date格式转化为LocalDate
     *
     * @param date date
     * @return LocalDate
     */
    public static LocalDate dateConvertToLocalDate(Date date) {
        return LocalDate.of(date.getYear() + 1900, date.getMonth() + 1, date.getDate());
    }


    /**
     * 只比较日期的年月日
     *
     * @param date1 date1
     * @param date2 date2
     * @return int
     */
    public static int compareDateWithLocalDate(Date date1, Date date2) {
        return dateConvertToLocalDate(date1).compareTo(dateConvertToLocalDate(date2));
    }

    /**
     * 根据传入的字符串返回localDate
     *
     * @param date string
     * @return LocalDate
     */
    public static LocalDate parse(String date) {
        if (null == date) {
            return null;
        }
        date = date.trim();
        if (Strings.isNullOrEmpty(date)) {
            return null;
        }
        String pattern = "%d{4}-%d{2}-%d{2}";
        Pattern compile = Pattern.compile(pattern);
        Matcher matcher = compile.matcher(date);
        if (matcher.matches()) {
            return LocalDate.parse(date);
        } else {
            return LocalDate.parse(date.substring(0, 10));
        }
    }

    public static Date format(String str) throws ParseException {
        DateFormat format = new SimpleDateFormat();
        Date date = format.parse(str);

        return date;
    }

    public static Date getBeforeDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    public static long compareDate(Date date, Date date1) {
        return (date.getTime() - date1.getTime()) / 1000;

    }

    /* 以下Jarod Chao添加 */

    /**
     * 按照指定的格式返回日期字符串. 默认 "yyyy-MM-dd"
     *
     * @param date
     * @param pattern
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        if (pattern == null) {
            pattern = DATE_PATTERN;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return (sdf.format(date));
    }

    /**
     * yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @return
     */
    public static String formatDateTime(Date date) {
        return (formatDate(date, DATETIME_PATTERN));
    }

    /**
     * 当前时间 yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String formatDateTime() {
        return (formatDate(now(), DATETIME_PATTERN));
    }

    /**
     * 当前时间 yyyyMMddHHmmss
     *
     * @return
     */
    public static String formatDateTime2() {
        return (formatDate(now(), PART_DATETIME_PATTERN));
    }

    /**
     * 当前时间(含毫秒) yyyyMMddHHmmssSSS
     *
     * @return
     */
    public static String formatDateTime3() {
        return (formatDate(now(), ALL_DATETIME_PATTERN));
    }

    /**
     * yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return (formatDate(date, DATE_PATTERN));
    }

    /**
     * 当前日期 yyyy-MM-dd
     *
     * @return
     */
    public static String formatDate() {
        return (formatDate(now(), DATE_PATTERN));
    }

    /**
     * 当前日期 yyyyMMdd
     *
     * @return
     */
    public static String formatDate2() {
        return (formatDate(now(), DATE_PATTERN_ANOTHER));
    }

    /**
     * yyyyMMdd
     *
     * @return
     */
    public static String formatDate2(Date date) {
        return (formatDate(date, DATE_PATTERN_ANOTHER));
    }


    /**
     * HH:mm:ss
     *
     * @param date
     * @return
     */
    public static String formatTime(Date date) {
        return (formatDate(date, TIME_PATTERN));
    }

    /**
     * 当前时间 HH:mm:ss
     *
     * @return
     */
    public static String formatTime() {
        return (formatDate(now(), TIME_PATTERN));
    }

    /**
     * 当前时间 HHmmss
     *
     * @return
     */
    public static String formatTime2() {
        return (formatDate(now(), TIME_PATTERN_ANOTHER));
    }

    /**
     * 当前时间 Date类型
     *
     * @return
     */
    public static Date now() {
        return (new Date());
    }

    public static LocalDate nowLocalDate() {
        return LocalDate.now();
    }

    public static LocalDateTime nowLocalDateTime() {
        return LocalDateTime.now();
    }

    /**
     * yyyy-MM-dd HH:mm:ss 转Date
     *
     * @param datetime
     * @return
     */
    public static Date parseDateTime(String datetime) {
        SimpleDateFormat formatter = new SimpleDateFormat(DATETIME_PATTERN);
        if (StringUtils.isBlank(datetime)) {
            return null;
        } else {
            try {
                return formatter.parse(datetime);
            } catch (ParseException e) {
                return parseDate(datetime);
            }
        }
    }

    /**
     * format 转Date
     *
     * @param date
     * @return
     */
    public static Date parseDate(String date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);

        if (StringUtils.isBlank(date)) {
            return null;
        } else {
            try {
                return formatter.parse(date);
            } catch (ParseException e) {
                return null;
            }
        }
    }

    /**
     * format 转Date
     *
     * @param date
     * @return
     */
    public static String parseStringDate(String date, String beforeFormat, String afterFomat) {
        SimpleDateFormat beforeFormatter = new SimpleDateFormat(beforeFormat);
        SimpleDateFormat afterFomatter = new SimpleDateFormat(afterFomat);


        if (StringUtils.isBlank(date)) {
            return null;
        } else {
            try {
                return afterFomatter.format(beforeFormatter.parse(date));
            } catch (ParseException e) {
                return null;
            }
        }
    }

    /**
     * yyyy-MM-dd 转Date
     *
     * @param date
     * @return
     */
    public static Date parseDate(String date) {
        SimpleDateFormat formatter = new SimpleDateFormat(DATE_PATTERN);

        if (StringUtils.isBlank(date)) {
            return null;
        } else {
            try {
                return formatter.parse(date);
            } catch (ParseException e) {
                return null;
            }
        }
    }

    public static Date parseDate(Date datetime) {
        SimpleDateFormat formatter = new SimpleDateFormat(DATE_PATTERN);

        if (datetime == null) {
            return null;
        } else {
            try {
                return formatter.parse(formatter.format(datetime));
            } catch (ParseException e) {
                return null;
            }
        }
    }

    public static String formatDate(Object o) {
        if (o == null) {
            return "";
        }
        if (o.getClass() == String.class) {
            return formatDate(o);
        } else if (o.getClass() == Date.class) {
            return formatDate((Date) o);
        } else if (o.getClass() == Timestamp.class) {
            return formatDate(new Date(((Timestamp) o).getTime()));
        } else {
            return o.toString();
        }
    }

    public static String formatDateTime(Object o) {
        if (o.getClass() == String.class) {
            return formatDateTime(o);
        } else if (o.getClass() == Date.class) {
            return formatDateTime((Date) o);
        } else if (o.getClass() == Timestamp.class) {
            return formatDateTime(new Date(((Timestamp) o).getTime()));
        } else {
            return o.toString();
        }
    }

    /**
     * 给时间加上或减去指定毫秒，秒，分，时，天、月或年等，返回变动后的时间
     *
     * @param date   要加减前的时间，如果不传，则为当前日期
     * @param field  时间域，有Calendar.MILLISECOND,Calendar.SECOND,Calendar.MINUTE,<br>
     *               Calendar.HOUR,Calendar.DATE, Calendar.MONTH,Calendar.YEAR
     * @param amount 按指定时间域加减的时间数量，正数为加，负数为减。
     * @return 变动后的时间
     */
    public static Date add(Date date, int field, int amount) {
        if (date == null) {
            date = new Date();
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(field, amount);

        return cal.getTime();
    }

    public static Date addMilliSecond(Date date, int amount) {
        return add(date, Calendar.MILLISECOND, amount);
    }

    public static Date addSecond(Date date, int amount) {
        return add(date, Calendar.SECOND, amount);
    }

    public static Date addMiunte(Date date, int amount) {
        return add(date, Calendar.MINUTE, amount);
    }

    public static Date addHour(Date date, int amount) {
        return add(date, Calendar.HOUR, amount);
    }

    public static Date addDay(Date date, int amount) {
        return add(date, Calendar.DATE, amount);
    }

    public static Date addMonth(Date date, int amount) {
        return add(date, Calendar.MONTH, amount);
    }

    public static Date addYear(Date date, int amount) {
        return add(date, Calendar.YEAR, amount);
    }

    /**
     * @return 当前日期 yyyy-MM-dd
     */
    public static Date getDate() {
        return parseDate(formatDate());
    }

    public static Date getDateTime() {
        return parseDateTime(formatDateTime());
    }

    public static boolean between(Date date, int offset, TimeUnit unit) {
        return System.currentTimeMillis() - date.getTime() <= unit.toMillis(offset);
    }

    /**
     * 间隔日时间
     *
     * @param date
     * @param interval
     * @return
     */
    public static Date getDate(Date date, int interval) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.get(Calendar.DATE) + interval);
        return cal.getTime();
    }

    /**
     * 间隔月时间
     *
     * @param date
     * @param interval
     * @return
     */
    public static Date getDateByMonth(Date date, int interval) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + interval);
        return cal.getTime();
    }

    /**
     * 间隔分钟时间
     *
     * @param date
     * @param interval
     * @return
     */
    public static Date getDateByMinute(Date date, int interval) {
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + interval);
        return cal.getTime();
    }

    /**
     * date1>date2 返回1，否则返回-1
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int compare(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        return cal1.compareTo(cal2);
    }

    /**
     * 比较俩个日期的大小  startDate>endDate返回false，否则返回true
     *
     * @param startDate 开始时间 yyyy-mm-dd
     * @param endDate   结束时间  yyyy-mm-dd
     * @return
     */
    public static boolean compare(String startDate, String endDate) {
        boolean flag = true;
        Date date1 = parseDate(startDate);
        Date date2 = parseDate(endDate);
        if (date1 == null || date2 == null || date1.compareTo(date2) > 0) {
            flag = false;
        }
        return flag;
    }

    /**
     * 获取两个日期之间的相差天数
     * @param date1
     * @param date2
     * @return
     */
    public static int getDaysBetween(Date date1, Date date2) {
        Calendar d1 = Calendar.getInstance();
        Calendar d2 = Calendar.getInstance();
        d1.setTime(date1);
        d2.setTime(date2);

        if (d1.after(d2)) {
            Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int days = d2.get(Calendar.DAY_OF_YEAR) - d1.get(Calendar.DAY_OF_YEAR);
        int y2 = d2.get(Calendar.YEAR);

        if (d1.get(Calendar.YEAR) != y2) {
            d1 = (Calendar) d1.clone();
            do {
                days += d1.getActualMaximum(Calendar.DAY_OF_YEAR);
                d1.add(Calendar.YEAR, 1);
            } while (d1.get(Calendar.YEAR) != y2);
        }
        return days;
    }

    /**
     * 获取两个日期相差天数
     * @param startDate
     * @param endDate
     * @return
     */
    public static int getDiffDays(Date startDate, Date endDate) {
        return (int) ((endDate.getTime() - startDate.getTime()) / (24 * 3600 * 1000));
    }

    /**
     * 根据日期获取年月日数组
     *
     * @param date 不能为null,该方法不做date为null判断,为null时不知返回什么信息
     * @return int[]{年，月，日}数组长度固定
     * exp :[2016, 05, 19]
     */
    public static String[] getYearAndMonthAndDay(Date date) {
        String strDate = DateUtils.formatDate(date, DATE_PATTERN);
        return new String[]{strDate.substring(0, 4), strDate.substring(5, 7),
                strDate.substring(8, 10)};
    }

    /**
     * 根据日期获取年
     *
     * @param date 不能为null,该方法不做date为null判断,为null时不知返回什么信息
     * @return
     */
    public static String getYear(Date date) {

        DateTime dt = new DateTime(date.getTime());

        int year = dt.year().get();

        return String.valueOf(year);
    }

    /**
     * 根据日期获取月
     *
     * @param date 不能为null,该方法不做date为null判断,为null时不知返回什么信息
     * @return
     */
    public static String getMonth(Date date) {

        DateTime dt = new DateTime(date.getTime());

        int month = dt.monthOfYear().get();

        if (month < 10) {
            return "0" + month;
        } else {
            return String.valueOf(month);
        }
    }

    /**
     * 根据日期获取日
     *
     * @param date 不能为null,该方法不做date为null判断,为null时不知返回什么信息
     * @return
     */
    public static String getDay(Date date) {
        DateTime dt = new DateTime(date.getTime());

        int day = dt.dayOfMonth().get();

        return String.valueOf(day);
    }

    public static boolean sameYear(long thisTime, long thatTime) {
        Calendar thisCalendar = Calendar.getInstance();
        thisCalendar.setTimeInMillis(thisTime);

        Calendar thatCalendar = Calendar.getInstance();
        thatCalendar.setTimeInMillis(thatTime);
        return thisCalendar.get(Calendar.YEAR) == thatCalendar.get(Calendar.YEAR);
    }

    public static boolean sameMonth(long thisTime, long thatTime) {
        Calendar thisCalendar = Calendar.getInstance();
        thisCalendar.setTimeInMillis(thisTime);

        Calendar thatCalendar = Calendar.getInstance();
        thatCalendar.setTimeInMillis(thatTime);
        return thisCalendar.get(Calendar.YEAR) == thatCalendar.get(Calendar.YEAR) &&
                thisCalendar.get(Calendar.MONTH) == thatCalendar.get(Calendar.MONTH);
    }

    public static boolean sameDate(long thisTime, long thatTime) {
        Calendar thisCalendar = Calendar.getInstance();
        thisCalendar.setTimeInMillis(thisTime);

        Calendar thatCalendar = Calendar.getInstance();
        thatCalendar.setTimeInMillis(thatTime);
        return thisCalendar.get(Calendar.YEAR) == thatCalendar.get(Calendar.YEAR) &&
                thisCalendar.get(Calendar.MONTH) == thatCalendar.get(Calendar.MONTH) &&
                thisCalendar.get(Calendar.DATE) == thatCalendar.get(Calendar.DATE);
    }

    /**
     * 增加或者减少年份
     *
     * @param date 当前时间
     * @param year 年份，正数为加，负数为减
     */
    public static Date toYear(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 根据date获取返回每个月的第一天的开始时间。
     * 若果date为空则返回当前月的第一天
     * 2017-01-01 00:00:00
     *
     * @return Date
     */
    public static Date getMonthStartTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }

        calendar.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        calendar.set(Calendar.MINUTE, 0);
        //将秒至0
        calendar.set(Calendar.SECOND, 0);
        //将毫秒至0
        calendar.set(Calendar.MILLISECOND, 0);
        //获得当前月第一天

        return calendar.getTime();
    }

    /**
     * 根据date获取返回每个月的最后一天的结束时间。
     * 若果date为空则返回当前月的最后一天
     * <p>
     * 2017-01-31 23:59:59
     *
     * @return Date
     */
    public static Date getMonthEndTime(Date date) {
        Calendar calendar = Calendar.getInstance();

        if (date != null) {
            calendar.setTime(date);
        }

        calendar.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        calendar.set(Calendar.MINUTE, 0);
        //将秒至0
        calendar.set(Calendar.SECOND, 0);
        //将毫秒至0
        calendar.set(Calendar.MILLISECOND, 0);

        //将当前月加1；
        calendar.add(Calendar.MONTH, 1);
        //在当前月的下一月基础上减去1毫秒
        calendar.add(Calendar.MILLISECOND, -1);
        //获得当前月最后一天
        return calendar.getTime();
    }

    public static Date[] getMonthStartEnd(Date d1, int months) {

        DateTime dt = new DateTime(d1.getTime());

        DateTime dt1 = new DateTime(d1.getTime());

        if (months < 0) {
            dt = dt1.minusMonths(Math.abs(months));
        } else if (months > 0) {
            dt = dt1.plusMonths(Math.abs(months));
        }

        int year = dt.year().get();
        int month = dt.monthOfYear().get();
        int start = dt.dayOfMonth().getMinimumValue();
        int end = dt.dayOfMonth().getMaximumValue();

        String format = "%s-%s-%s";
        String startDate = String.format(format, year, month, start);
        String endDate = String.format(format, year, month, end);

        return Stream.of(DateUtils.parseDate(startDate), DateUtils.parseDate(endDate))
                .toArray(Date[]::new);

    }

    public static Date getWorkingDate() {
        return new Date();
    }

    public static Date getDateByCurrDateAndDays(Date currDate, int days) throws ParseException {
        String outDate;
        String pattern = DATE_PATTERN;
        Calendar theCa = Calendar.getInstance();
        theCa.setTime(currDate);
        theCa.add(Calendar.DATE, -days);
        Date date = theCa.getTime();
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        outDate = format.format(date);
        return format.parse(outDate);
    }

    public static Date[] getDayTerm(Date date) {
        String startDate = DateUtils.formatDate(date) + " 00:00:00";
        String endDate = DateUtils.formatDate(date) + " 23:59:59";

        return Stream
                .of(DateUtils.parseDateTime(startDate), DateUtils.parseDateTime(endDate))
                .toArray(Date[]::new);

    }

    public static Date[] getDayTerm(Date d1, Date d2) {
        String startDate = DateUtils.formatDate(d1) + " 00:00:00";
        String endDate = DateUtils.formatDate(d2) + " 23:59:59";

        return Stream
                .of(DateUtils.parseDateTime(startDate), DateUtils.parseDateTime(endDate))
                .toArray(Date[]::new);

    }
    /* ********************** */

    /**
     * date1 在 date2 的前一天或前几天返回true，否则返回false
     *
     * @param date1
     * @param date2
     * @return boolean
     * @author zhixuan.xue
     */
    public static boolean beforeDay(Date date1, Date date2) {
        return DateUtils.compare(date1, date2) == -1 &&
                DateUtils.getDaysBetween(date1, date2) > 0;
    }

    /**
     * 获取一个月的天数
     *
     * @param date
     * @return
     */
    public static int getTotalDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取业务时间
     *
     * @param effectiveDate
     * @param businessDate
     */
    public static Date getBusinessTime(Date effectiveDate, Date businessDate) {

        if (effectiveDate == null) {
            return businessDate;
        }
        Calendar effectiveCalendar = Calendar.getInstance();
        effectiveCalendar.setTime(effectiveDate);
        Calendar businessCalendar = Calendar.getInstance();
        businessCalendar.setTime(businessDate);
        effectiveCalendar.set(Calendar.YEAR, businessCalendar.get(Calendar.YEAR));
        effectiveCalendar.set(Calendar.MONTH, businessCalendar.get(Calendar.MONTH));
        effectiveCalendar.set(Calendar.DATE, businessCalendar.get(Calendar.DATE));
        Date businessTime = effectiveCalendar.getTime();
        return businessTime;

    }

    /**
     * 获取x日为本月的x日
     *
     * @param date
     * @param day
     * @return
     */
    public static Date getThisMonthDate(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        if (date != null) {
            calendar.setTime(date);
        }

        calendar.set(Calendar.DAY_OF_MONTH, day);
        return calendar.getTime();
    }

    /**
     * 获取x日为本月的x日
     *
     * @param dateString
     * @param day
     * @return
     */
    public static Date getThisMonthDate(String dateString, String format, int day) {
        Date date = parseDate(dateString, format);
        return getThisMonthDate(date, day);
    }

    /**
     * 获取上一月的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastMonthLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        int month = calendar.get(Calendar.MONTH);

        calendar.set(Calendar.MONTH, month - 1);

        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 获取上一季的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastQuarterYearly(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        int month = calendar.get(Calendar.MONTH);

        calendar.set(Calendar.MONTH, month - 3);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 获取上一年的这一天
     *
     * @param date
     * @return
     */
    public static Date getLastYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        calendar.set(Calendar.YEAR, year - 1);
        return calendar.getTime();
    }

    /**
     * 判断日期月份是否为某一季末
     *
     * @param date
     * @return
     */
    public static boolean isQuarterYearly(Date date) {

        DateTime dt = new DateTime(date.getTime());

        int month = dt.monthOfYear().get();

        if (month == 3 || month == 6 || month == 9 || month == 12) {
            return true;
        }
        return false;
    }

    /**
     * 根据首期还款日与当前业务日期获取当月还款日
     *
     * @param payDate      首期还款日
     * @param businessDate 当前业务日期
     * @return
     */
    public static Date calculationPayDate(Date payDate, Date businessDate) {
        Date patmentDueDate = null;

        //间隔月份
        int strBusDate = Integer.parseInt(DateUtils.format(businessDate).substring(5, 7));
        int strPayDate = Integer.parseInt(DateUtils.format(payDate).substring(5, 7));
        int mon = strBusDate - strPayDate;

        Date currPaymentDate = DateUtils.addMonth(payDate, mon);
        if (currPaymentDate.compareTo(businessDate) <= 0) {
            patmentDueDate = DateUtils.addMonth(payDate, mon + 1);
        } else {
            patmentDueDate = currPaymentDate;
        }

        return patmentDueDate;
    }

    /**
     * 判断当前业务日期是否为还款日
     *
     * @param payDate
     * @param businessDate
     * @return
     */
    public static Boolean checkPaymentDate(Date payDate, Date businessDate) {
        //间隔月份
        int strBusDate = Integer.parseInt(DateUtils.format(businessDate).substring(5, 7));
        int strPayDate = Integer.parseInt(DateUtils.format(payDate).substring(5, 7));
        int mon = strBusDate - strPayDate;

        Date currPaymentDate = DateUtils.addMonth(payDate, mon);
        if (businessDate.compareTo(currPaymentDate) == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取当周 周几时间 日期格式：yyyy-MM-dd
     *
     * @param dayOfWeek
     * @return
     */
    public static String getDayOfWeek(int dayOfWeek) {
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cld = Calendar.getInstance(Locale.CHINA);
        //以周一为首日
        cld.setFirstDayOfWeek(Calendar.MONDAY);
        //当前时间
        cld.setTimeInMillis(System.currentTimeMillis());

        cld.set(Calendar.DAY_OF_WEEK, dayOfWeek);
        return df.format(cld.getTime());
    }

    /**
     * 获取2个日期间隔天数
     *
     * @param endDate 开始时间
     * @param nowDate 结束日期
     * @return 间隔天数
     */
    public static long getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;

        long diff = endDate.getTime() - nowDate.getTime();

        long day = diff / nd;

        return day;
    }

    /**
     * 获取指定间隔月前的日期
     *
     * @param date
     * @return
     */
    public static Date getMonthDays(Date date, int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int month = calendar.get(Calendar.MONTH);
        calendar.set(Calendar.MONTH, month - i);
        return calendar.getTime();
    }

    /**
     * 获取当月第几天的日期（String 格式）
     * @param dayOfMonth
     * @return
     */
    public static String getDayOfCurrentMonthDay(int dayOfMonth){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        return format.format(c.getTime());
    }

    /**
     * 获取当天是周几
     * @return
     */
    public static Integer getCurrentDayOfWeek(){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        int dayForWeek = 0;
        if(c.get(Calendar.DAY_OF_WEEK) == 1){
            dayForWeek = 7;
        }else{
            dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        }
        return dayForWeek;
    }

    /**
     * 获取当天是当月的第几天
     * @return
     */
    public static Integer getCurrentDayOfMonth(){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取两个月相差月份
     * @return
     */
    public static Integer calcGapMonths(Date befDate, Date aftDate){
        Calendar c = Calendar.getInstance();
        c.setTime(befDate);
        int month = c.get(Calendar.MONTH);
        int year = c.get(Calendar.YEAR);
        c.setTime(aftDate);
        month = c.get(Calendar.MONTH) - month;
        year = c.get(Calendar.YEAR) - year;
        return Math.abs(year*12 + month);
    }

    /**
     * 获取当前季度第一天
     * @return
     */
    public static String getCurrentQuarterFirst(){
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal=Calendar.getInstance();
        String currentQuarter = getCurrentQuarter();
        String firstDay = "";
        switch (currentQuarter){
            case "1":
                cal.set(Calendar.MONTH,0);
                break;
            case "2":
                cal.set(Calendar.MONTH,3);
                break;
            case "3":
                cal.set(Calendar.MONTH,6);
                break;
            case "4":
                cal.set(Calendar.MONTH,9);
                break;
        }
        cal.set(Calendar.DATE,1);
        firstDay =  df.format(cal.getTime());
        return firstDay;
    }

    /**
     * 根据当前入参获取对应季度的第一天
     * @param date
     * @return
     */
    public static Date getQuarterFirstDate(Date date) {
        Calendar cal = Calendar.getInstance();
        if (Objects.nonNull(date)) {
            cal.setTime(date);
        }
        int currentQuarter = getQuarterByDate(date);
        switch (currentQuarter) {
            case 1:
                cal.set(Calendar.MONTH, 0);
                break;
            case 2:
                cal.set(Calendar.MONTH, 3);
                break;
            case 3:
                cal.set(Calendar.MONTH, 6);
                break;
            case 4:
                cal.set(Calendar.MONTH, 9);
                break;
        }
        cal.set(Calendar.DATE, 1);
        return cal.getTime();
    }

    /**
     * 根据日期获取当前在其月份中的第几天
     * @param date
     * @return
     */
    public static int getDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        if (Objects.nonNull(date)) {
            cal.setTime(date);
        }
        return cal.get(Calendar.DAY_OF_MONTH);
    }
    /**
     * 根据日期获取当前在其年中的第几天
     * @param date
     * @return
     */
    public static int getDayOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        if (Objects.nonNull(date)) {
            cal.setTime(date);
        }
        return cal.get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 获取当前季度最后一天
     * @return
     */
    public static String getCurrentQuarterLast(){
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal=Calendar.getInstance();
//        String currentQuarter = getCurrentQuarter();
        String currentQuarter = "4";
        String lastDay = "";
        switch (currentQuarter){
            case "1":
                cal.set(Calendar.MONTH,2);
                cal.set(Calendar.DATE,31);
                break;
            case "2":
                cal.set(Calendar.MONTH,5);
                cal.set(Calendar.DATE,30);
                break;
            case "3":
                cal.set(Calendar.MONTH,8);
                cal.set(Calendar.DATE,30);
                break;
            case "4":
                cal.set(Calendar.MONTH,11);
                cal.set(Calendar.DATE,31);
                break;
        }

        lastDay =  df.format(cal.getTime());
        return lastDay;
    }

    /**
     * 获取当前季度
     * @return
     */
    public static String getCurrentQuarter(){
        Calendar cal = Calendar.getInstance();
        int month = cal.get(cal.MONTH) + 1;
        int quarter = 0;
        if (month >= 1 && month <= 3) {
            quarter = 1;
        } else if (month >= 4 && month <= 6) {
            quarter = 2;
        } else if (month >= 7 && month <= 9) {
            quarter = 3;
        } else {
            quarter = 4;
        }
        return quarter + "";
    }

    /**
     * 根据时间获取当前季度
     * @return
     */
    public static int getQuarterByDate(Date date) {
        Calendar cal = Calendar.getInstance();
        if (Objects.nonNull(date)) {
            cal.setTime(date);
        }
        int month = cal.get(Calendar.MONTH) + 1;
        int quarter;
        if (month <= 3) {
            quarter = 1;
        } else if (month <= 6) {
            quarter = 2;
        } else if (month <= 9) {
            quarter = 3;
        } else {
            quarter = 4;
        }
        return quarter;
    }

    /**
     * 获取本年第一天
     * @return
     */
    public static String getCurrentYearFirst(){
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_YEAR,1);
        return df.format(cal.getTime());
    }

    /**
     * 根据日期获取当年第一天
     * @return
     */
    public static Date getCurrentYearFirst(Date date) {
        //设置日期格式
        Calendar cal = Calendar.getInstance();
        if (Objects.nonNull(date)) {
            cal.setTime(date);
        }
        cal.set(Calendar.DAY_OF_YEAR, 1);
        return cal.getTime();
    }

    /**
     * 获取本年最后一天
     * @return
     */
    public static String getCurrentYearLast(){
        //设置日期格式
        SimpleDateFormat df = new SimpleDateFormat("yyyy");
        return df.format(new Date())+"-12-31";
    }
}
